{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ec367996",
   "metadata": {},
   "source": [
    "## Computing the incidence of a COVID-19 outcome variable (e.g. deaths), by vax status.\n",
    "\n",
    "There are two common methodologies:\n",
    "1. Compare aggregate data on deaths by vax status (numerator) to population by vax status (denominator) \n",
    "2. Compute incidence rates by tracking a representative sample of individuals\n",
    "\n",
    "The validity of Method 1 hinges on whether we are confident in population estimates, since the unvaccinated population is not tracked in the same way that each vaccination is, and is hence derived as:\n",
    "\n",
    "`unvax  = total population - total with at least 1 dose`\n",
    "\n",
    "This relies on an accurate estimates of:\n",
    "- Total population\n",
    "- Number of vaccinated people\n",
    "\n",
    "Vaccinations are tracked rigorously in Malaysia, but a robust population estimate may be difficult to obtain, given the ostensibly large undocumented population. \n",
    "\n",
    "In the context of vaccinations, an indicator that there is uncertainty over population data is when the number of vaccinations delivered exceeds the total population estimate. This problem is particularly salient in Malaysia, because primary vaccination rates are >90% across all age groups. This means that even small errors in population estimates (which are a regular feature of censusus, and not due to any fault of the census-taker) can lead to an implied negative unvaccinated group. For example, as of the 10th of March, the number of vaccinated individuals aged 50-59 exceeds the population estimate for that age group.\n",
    "\n",
    "Therefore, it may be preferable to use Method 2, and track a representative sample of individuals, especially if a comprehensive population database is available. With such a database, COVID-19 testing, outcomes (hosp, ICU, death), and vaccination history are matched based on individual IDs; computed incidence rates are guaranteed to be bounded between 0 and 100%.\n",
    "\n",
    "That said, this notebook is intended to demonstrate the application of Method 1. However, we use population numbers derived from our application of Method 2."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "98976dd8",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from tabulate import tabulate\n",
    "\n",
    "import numpy as np\n",
    "import datetime\n",
    "from datetime import date, timedelta\n",
    "\n",
    "import seaborn as sb\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.patches as mpatches\n",
    "from matplotlib.lines import Line2D\n",
    "import matplotlib.ticker as tkr\n",
    "\n",
    "linelist_deaths = 'https://raw.githubusercontent.com/MoH-Malaysia/covid19-public/main/epidemic/linelist/linelist_deaths.csv'\n",
    "vax_age = 'https://raw.githubusercontent.com/MoH-Malaysia/covid19-public/main/vaccination/vax_demog_age.csv'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "51b66f2d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# The first set of numbers is taken directly from DOSM's latest release (Feb 14), with imputation only to back out the 18-29 group.\n",
    "# This set of population numbers gives us an adult population of ~23.1mil\n",
    "\n",
    "pop_age = {\n",
    "'18_29' : 7067431,\n",
    "'30_39' : 5636728,\n",
    "'40_49' : 4021654,\n",
    "'50_59' : 3030048,\n",
    "'60_69' : 2050943,\n",
    "'70_79' : 956402,\n",
    "'80+' : 326759,\n",
    "}\n",
    "\n",
    "# This is the adjusted set, derived from supplementing national registration data with data collected via the vaccination program.\n",
    "# This set of population numbers gives us an adult population of ~24mil, which drastically affects the size of the unvax population.\n",
    "# Comment it out to use the first set.\n",
    "\n",
    "pop_age = {\n",
    "'18_29' : 7563410,\n",
    "'30_39' : 5740871,\n",
    "'40_49' : 4021654,\n",
    "'50_59' : 3121816,\n",
    "'60_69' : 2180719,\n",
    "'70_79' : 1001044,\n",
    "'80+' : 337123,\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "4fc8886f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>status</th>\n",
       "      <th>deaths</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>18_29</td>\n",
       "      <td>boosted</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>18_29</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>18_29</td>\n",
       "      <td>unvax</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>30_39</td>\n",
       "      <td>boosted</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>30_39</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>30_39</td>\n",
       "      <td>unvax</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>40_49</td>\n",
       "      <td>boosted</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>40_49</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>31</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>40_49</td>\n",
       "      <td>unvax</td>\n",
       "      <td>18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>50_59</td>\n",
       "      <td>boosted</td>\n",
       "      <td>21</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>50_59</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>55</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>50_59</td>\n",
       "      <td>unvax</td>\n",
       "      <td>26</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>60_69</td>\n",
       "      <td>boosted</td>\n",
       "      <td>32</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>60_69</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>87</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>60_69</td>\n",
       "      <td>unvax</td>\n",
       "      <td>32</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>70_79</td>\n",
       "      <td>boosted</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>70_79</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>103</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>70_79</td>\n",
       "      <td>unvax</td>\n",
       "      <td>48</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>80+</td>\n",
       "      <td>boosted</td>\n",
       "      <td>29</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>80+</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>103</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>80+</td>\n",
       "      <td>unvax</td>\n",
       "      <td>92</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      age    status  deaths\n",
       "0   18_29   boosted       2\n",
       "1   18_29  fullyvax       5\n",
       "2   18_29     unvax       7\n",
       "3   30_39   boosted       4\n",
       "4   30_39  fullyvax      11\n",
       "5   30_39     unvax       8\n",
       "6   40_49   boosted      12\n",
       "7   40_49  fullyvax      31\n",
       "8   40_49     unvax      18\n",
       "9   50_59   boosted      21\n",
       "10  50_59  fullyvax      55\n",
       "11  50_59     unvax      26\n",
       "12  60_69   boosted      32\n",
       "13  60_69  fullyvax      87\n",
       "14  60_69     unvax      32\n",
       "15  70_79   boosted      37\n",
       "16  70_79  fullyvax     103\n",
       "17  70_79     unvax      48\n",
       "18    80+   boosted      29\n",
       "19    80+  fullyvax     103\n",
       "20    80+     unvax      92"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Key parameters - choose timerange and whether to use date of death or date of report.\n",
    "# Note: Intervals longer than 21 days are not advisable, as there may be large changes in the vax population. This requires different handling.\n",
    "\n",
    "date_min = date.today()-timedelta(14)\n",
    "date_max = date.today()-timedelta(1)\n",
    "use_announced = 0\n",
    "\n",
    "def vaxStatus(date_pos, date1, date2, date3):\n",
    "    if (date_pos - date3).days > 6: return 'boosted'\n",
    "    elif (date_pos - date2).days > 13: return 'fullyvax'\n",
    "    elif (date_pos - date1).days >= 0: return 'partialvax'\n",
    "    else: return 'unvax'\n",
    "    \n",
    "def castAge(age):\n",
    "    if age == -1: return 'missing'\n",
    "    elif age < 5: return '0_4'\n",
    "    elif age < 12: return '5_11'\n",
    "    elif age < 18: return '12_17'\n",
    "    elif age < 30: return '18_29'\n",
    "    elif age < 40: return '30_39'\n",
    "    elif age < 50: return '40_49'\n",
    "    elif age < 60: return '50_59'\n",
    "    elif age < 70: return '60_69'\n",
    "    elif age < 80: return '70_79'\n",
    "    else: return '80+'\n",
    "\n",
    "ages = [x for x in range(-1,150)]\n",
    "age_cat = dict(zip(ages,[castAge(x) for x in ages]))\n",
    "\n",
    "# Pull latest deaths linelist and wrangle\n",
    "datecol = 'date_announced' if use_announced == 1 else 'date'\n",
    "df = pd.read_csv(linelist_deaths, usecols=[datecol, 'age', 'date_positive','date_dose1','date_dose2','date_dose3','brand1'])\n",
    "df = df.rename(columns={'date_announced':'date'})\n",
    "for c in ['date','date_positive','date_dose1','date_dose2','date_dose3']: df[c] = pd.to_datetime(df[c],errors='coerce').dt.date\n",
    "df = df[(df.date >= date_min) & (df.date <= date_max)]\n",
    "\n",
    "# Ensure no null vax dates (future date as placeholder), shift 14 days for Cansino, then encode vax status and age group\n",
    "for c in ['date_dose1','date_dose2','date_dose3']: df[c] = df[c].fillna(date.today()+timedelta(1))\n",
    "df.loc[df.brand1.isin(['Cansino']),'date_dose2'] = df.date_dose1 + timedelta(14)\n",
    "df['status'] = df.apply(lambda x: vaxStatus(x['date_positive'],x['date_dose1'],x['date_dose2'],x['date_dose3']),axis=1)\n",
    "df = df.replace(date.today()+timedelta(1),np.nan) # Remove placeholder dates\n",
    "df.age = df.age.map(age_cat) # Encode age group\n",
    "\n",
    "# Tabulate, keeping adults only\n",
    "df = df[~df.age.isin(['0_4','5_11','12_17'])].groupby(['age','status']).size().to_frame('deaths').reset_index()\n",
    "df = df[~df.status.isin(['partialvax'])].reset_index(drop=True)\n",
    "df.head(len(df))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "4bda6acd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>status</th>\n",
       "      <th>pop</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>18_29</td>\n",
       "      <td>boosted</td>\n",
       "      <td>3.705926e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>18_29</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>3.365107e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>18_29</td>\n",
       "      <td>unvax</td>\n",
       "      <td>6.874169e+05</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>30_39</td>\n",
       "      <td>boosted</td>\n",
       "      <td>3.271216e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>30_39</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>2.159248e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>30_39</td>\n",
       "      <td>unvax</td>\n",
       "      <td>4.087766e+05</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>40_49</td>\n",
       "      <td>boosted</td>\n",
       "      <td>2.649834e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>40_49</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>1.347461e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>40_49</td>\n",
       "      <td>unvax</td>\n",
       "      <td>8.114514e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>50_59</td>\n",
       "      <td>boosted</td>\n",
       "      <td>2.108867e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>50_59</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>9.666521e+05</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>50_59</td>\n",
       "      <td>unvax</td>\n",
       "      <td>7.987700e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>60_69</td>\n",
       "      <td>boosted</td>\n",
       "      <td>1.537019e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>60_69</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>6.041959e+05</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>60_69</td>\n",
       "      <td>unvax</td>\n",
       "      <td>6.098950e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>70_79</td>\n",
       "      <td>boosted</td>\n",
       "      <td>6.857932e+05</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>70_79</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>2.698364e+05</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>70_79</td>\n",
       "      <td>unvax</td>\n",
       "      <td>5.298864e+04</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>80+</td>\n",
       "      <td>boosted</td>\n",
       "      <td>2.012319e+05</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>80+</td>\n",
       "      <td>fullyvax</td>\n",
       "      <td>1.062509e+05</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>80+</td>\n",
       "      <td>unvax</td>\n",
       "      <td>3.086779e+04</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      age    status           pop\n",
       "0   18_29   boosted  3.705926e+06\n",
       "1   18_29  fullyvax  3.365107e+06\n",
       "2   18_29     unvax  6.874169e+05\n",
       "3   30_39   boosted  3.271216e+06\n",
       "4   30_39  fullyvax  2.159248e+06\n",
       "5   30_39     unvax  4.087766e+05\n",
       "6   40_49   boosted  2.649834e+06\n",
       "7   40_49  fullyvax  1.347461e+06\n",
       "8   40_49     unvax  8.114514e+04\n",
       "9   50_59   boosted  2.108867e+06\n",
       "10  50_59  fullyvax  9.666521e+05\n",
       "11  50_59     unvax  7.987700e+04\n",
       "12  60_69   boosted  1.537019e+06\n",
       "13  60_69  fullyvax  6.041959e+05\n",
       "14  60_69     unvax  6.098950e+04\n",
       "15  70_79   boosted  6.857932e+05\n",
       "16  70_79  fullyvax  2.698364e+05\n",
       "17  70_79     unvax  5.298864e+04\n",
       "18    80+   boosted  2.012319e+05\n",
       "19    80+  fullyvax  1.062509e+05\n",
       "20    80+     unvax  3.086779e+04"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Get vax by age data and wrangle\n",
    "cols_vax = ['date'] + [x + '_' + y.replace('+','') for x in ['partial','full','booster'] for y in list(pop_age.keys())]\n",
    "vf = pd.read_csv(vax_age,usecols=cols_vax)\n",
    "vf.columns = [x.replace('80','80+') for x in vf.columns]\n",
    "vf.date = pd.to_datetime(vf.date).dt.date\n",
    "vf = vf.groupby(['date']).sum().cumsum().reset_index()\n",
    "\n",
    "# Add unvax columns, subtract partial from unvax, full from partial, and boosted from full\n",
    "for c in list(pop_age.keys()): \n",
    "    vf['unvax_' + c] = pop_age[c] - vf['partial_' + c]\n",
    "    vf['partial_' + c] = vf['partial_' + c] - vf['full_' + c]\n",
    "    vf['full_' + c] = vf['full_' + c] - vf['booster_' + c]\n",
    "    \n",
    "# Shift vax columns per definitions of partial, full, boosted\n",
    "for c in [x for x in vf.columns if 'partial' in x]: vf[c] = vf[c].shift(1).fillna(0).astype(int)\n",
    "for c in [x for x in vf.columns if 'full' in x]: vf[c] = vf[c].shift(14).fillna(0).astype(int)\n",
    "for c in [x for x in vf.columns if 'booster' in x]: vf[c] = vf[c].shift(7).fillna(0).astype(int)\n",
    "\n",
    "# Get mean across period and transpose to merge with deaths df\n",
    "vf = vf[(vf.date >= date_min) & (vf.date <= date_max)]\n",
    "vf.drop(['date'],axis=1,inplace=True)\n",
    "vf.loc['pop'] = vf.mean(numeric_only=True)\n",
    "vf = vf[vf.index == 'pop'].transpose().reset_index().rename(columns={'index':'cat'})\n",
    "vf[['status','age']] = vf['cat'].str.split('_', 1, expand=True)\n",
    "vf.status = vf.status.replace({'partial':'partialvax', 'full':'fullyvax', 'booster':'boosted'})\n",
    "vf = vf[~vf.status.isin(['partialvax'])][['age','status','pop']].sort_values(by=['age','status']).reset_index(drop=True)\n",
    "vf.head(len(vf))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "cb2241ea",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>Unvaccinated</th>\n",
       "      <th>Fully Vaccinated</th>\n",
       "      <th>Boosted</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>18_29</td>\n",
       "      <td>1.018305</td>\n",
       "      <td>0.148584</td>\n",
       "      <td>0.053968</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>30_39</td>\n",
       "      <td>1.957059</td>\n",
       "      <td>0.509437</td>\n",
       "      <td>0.122279</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>40_49</td>\n",
       "      <td>22.182474</td>\n",
       "      <td>2.300623</td>\n",
       "      <td>0.452859</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>50_59</td>\n",
       "      <td>32.550046</td>\n",
       "      <td>5.689741</td>\n",
       "      <td>0.995795</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>60_69</td>\n",
       "      <td>52.468048</td>\n",
       "      <td>14.399303</td>\n",
       "      <td>2.081952</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>70_79</td>\n",
       "      <td>90.585449</td>\n",
       "      <td>38.171283</td>\n",
       "      <td>5.395212</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>80+</td>\n",
       "      <td>298.045350</td>\n",
       "      <td>96.940394</td>\n",
       "      <td>14.411237</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     age  Unvaccinated  Fully Vaccinated    Boosted\n",
       "0  18_29      1.018305          0.148584   0.053968\n",
       "1  30_39      1.957059          0.509437   0.122279\n",
       "2  40_49     22.182474          2.300623   0.452859\n",
       "3  50_59     32.550046          5.689741   0.995795\n",
       "4  60_69     52.468048         14.399303   2.081952\n",
       "5  70_79     90.585449         38.171283   5.395212\n",
       "6    80+    298.045350         96.940394  14.411237"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Merge frames and compute incidence, then pivot\n",
    "df = pd.merge(df,vf, on=['age','status'], how='left')\n",
    "df['capita'] = df.deaths/df['pop'] * 100000\n",
    "df = df.pivot(index='age', columns='status', values=['capita']).fillna(0).reset_index()\n",
    "df.columns = ['age','Boosted','Fully Vaccinated','Unvaccinated']\n",
    "df = df[['age','Unvaccinated','Fully Vaccinated','Boosted']]\n",
    "df.head(len(df))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "5936b93b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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warDk08+OaBtFRGRaNMcnAQ1AW8P0L+mPu5z+vTp1NXV0dLSwr59+1i7dm2PV14tWLCApUuX8tRTT7Fw4UIAduzYwaRJkxg7dixr1qyhqqqqc/3zzz+fBx54AAiGmd55550eyxPR034hODPU3Nzc+fjss8/mxRdfpL6+HoCNGzd2npl6+eWX2bt3L2vXrmXjxo0Jt0VERI4eOoOTgJycHK6trh7wOnuTkZHBF7/4Rc4880zcnauvvpq8vLxu158wYQInnHAC7733HunpwUXtF110Effddx+zZs3i5JNPprCwsHP9u+++m8WLF/Pzn/+ckSNH8sgjj3D88cfHLd+9ezcLFy6kubmZlpYWysrK+M53vsPHPvaxuG3pab8QzPNZuHAhEyZM4IknniAjI4N77rmH+fPn09bWxrhx43j44YfJycnhuuuu4/TTT2fWrFn6ugQREemRufugNqCoqMi7TlYdSl5//XVmzpw52M2QIUKvBxEZDDU1NTyTl9ev25S8DVzSh3uvDUNxbzOvISoRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYmcEYPdgOGkvb2d2traAa0zJyeHpKSkAa1TRETkaKeAk4Da2lqWLVvG1KlTB6S+zZs3A5Cbm9vjellZWaSmpnYGoW9961ssWLAg7rrV1dV84hOf4M0336S0tJSioqIeyxP1hS98gfz8fG666SYA7r33Xl599VV++ctfHlJ93XnqqadYu3Ytt912W7/qWbJkCYsXL2bs2LEJbTd79myWLl1KVlZWv/YvIiKDQwEnQVOnTh2UD71ly5YxadKkXtfLy8tj5cqVfOhDH+pTeaLmzZvHo48+2hlwli9fzvz58/tVZzwLFizoNsQlYsmSJVx11VUJBxwRERneNAdnGEtJSen8+UMf+hAVFRUJ1/H000/z6U9/uvPx7bffzo9//ONu17/gggt46aWXOh+/+OKLfPjDHwZg/vz5FBQUUFRUxE9/+tPOdRoaGliwYAEFBQWcccYZ1NTU9Fh+zTXXcOKJJ3LzzTcf9HxvueUWcnNzueGGGzrL4+33ueee47TTTmPLli2cf/75nT93POezzjqLgoIC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ZsOGDTpOOk46TjpOOk6DcJw6+rC/ysvLGT9+fKSOU1paWtznau7ep04xswzgOeAyoBD4qLvfEC57DPgVQcA5qNzd/9hdvUVFRd7RISIiInKwmpoansnL44R+1PE2cEl1Nbm5uQPVrKHC4hX26QyOmY0GngC+6u61ZnYCHNDPGQR9l9JNuYiIiMgR02vAMTMDHgAecfdnw+JXgXwzSyeYTJwJrArri1cuIiIicsT05QzOucAVwMxw7gzAx4DbgJfCx18Jr5R6z8zilYuIiIgcMX25iqoMGBln0ePhv67rxy0XEREROVJ0J2MRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiRwFHBEREYkcBRwRERGJHAUcERERiZxeA46Z/cDMGs1sdUxZu5mtDP/dHVN+pZmtM7MaM5t/uBotIiIi0pMRfVjnd8BjwIMxZS3uflrsSmY2Cvg+cDaQDCwzs2fcff/ANFVERESkb3o9g+PuLwPv9qGuYmCNuze6+1vAJuDUfrZPREREJGF9OYMTz2gzqwRagH929xeADOBtM7sRaAYagBOAlV03NrPFwGKAKVOmUFpaCsD06dNJTU2lqqoKgIkTJ5Kfn88LL7wQNHbECEpKSqisrGTHjh0AFBUV0djYyKZNmwCYMWMGycnJrF4djKilp6eTm5tLWVkZAMnJycyZM4eKigp27doFQHFxMfX19WzevBmAvLw8kpKSWLt2LQAZGRlkZ2ezYsUKAMaMGUNxcTHl5eW0tLQAMGfOHNavX09DQwMAs2bNor29nerqagCmTp1KZmYm5eXlAKSkpFBUVMSKFStobW0FoKSkhJqaGpqamgCYPXs2ra2trFu3DoBp06YxefJkKioqAEhLS6OwsJCysjLa2toAOO+881izZg1bt24FoKCggJ07d1JXVwdAVlYWEyZMoLKyEoDjjjuOgoICli9fjrtjZsydO5eqqiq2bdsGQGFhIc3NzWzYsEHHScdJx0nHScdpEI5TRx/2V3l5OePHj4/UcUpLS4v7XM3de+0QM8sClrr77PBxhrs3mNmZwJPADOBS4KPufkO4zmPAr9z9jz3VXVRU5B0dIiIiIgerqanhmbw8TuhHHW8Dl1RXk5ubO1DNGiosXuEhXUXl7g3h/68BW4Asgr6L7fuMsExERETkiEp4iMrMJhBMMm4Jz+xMBd4CaoF8M0snmGScCawawLaKiIiI9EmvAcfMfgZcDkwys3rgPuDTZtYKtAPXu/vucN3bgJfCTb+iK6hERERkMPQacNz9JuCmLsXf6mbdx4HHB6BdIiIiIodMdzIWERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyFHAERERkchRwBEREZHIUcARERGRyOk14JjZD8ys0cxWx5RdaWbrzKzGzOb3Vi4iIiJyJPXlDM7vgEs6HpjZKOD7QAkwD1hiZsd0Vz7wTRYRERHp2YjeVnD3l80sK6aoGFjj7o0AZrYJOBVI7aZ85QC3WURERKRHvQacODKAt83sRqAZaABOAFK6KV/ZtQIzWwwsBpgyZQqlpaUATJ8+ndTUVKqqqgCYOHEi+fn5vPDCC0FjR4ygpKSEyspKduzYAUBRURGNjY1s2rQJgBkzZpCcnMzq1cGIWnp6Orm5uZSVlQGQnJzMnDlzqKioYNeuXQAU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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Chart\n",
    "\n",
    "def commaSep(x, pos): return ('{:,}'.format(x)).replace('.0', '')\n",
    "\n",
    "plt.rcParams.update({'font.size': 10,\n",
    "                     'font.family':'Monospace',\n",
    "                     'grid.linestyle':'dashed'})\n",
    "plt.rcParams[\"figure.figsize\"] = [8,6]\n",
    "plt.rcParams[\"figure.autolayout\"] = True\n",
    "fig, ax = plt.subplots()\n",
    "\n",
    "df.plot(x='age', y=['Unvaccinated','Fully Vaccinated','Boosted'], kind='bar', \n",
    "        color=['#a70000','lightgray','#183f78'],\n",
    "        align='center',\n",
    "        width=0.7,linewidth=0.3,\n",
    "        edgecolor='black',ax=ax)\n",
    "ax.spines['top'].set_visible(False)\n",
    "ax.spines['right'].set_visible(False)\n",
    "\n",
    "ax.yaxis.grid(True)\n",
    "ax.set_axisbelow(True)\n",
    "ax.legend(loc='upper center', bbox_to_anchor=(0.2, 0.95), ncol=1, labelspacing = 1.5, frameon=True, fancybox=True)\n",
    "plt.xticks(rotation=0)\n",
    "ax.yaxis.set_major_formatter(tkr.FuncFormatter(commaSep))\n",
    "plt.tick_params(bottom=False)\n",
    "\n",
    "plt.title('Deaths per 100k People by Vax Status \\n\\n' + \n",
    "          '(data from ' + date_min.strftime('%d-%b') + ' to ' + date_max.strftime('%d-%b') + ')')\n",
    "plt.xlabel('')\n",
    "plt.ylabel('')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
